import time
import threading

class CPU(threading.Thread):
    
    
    def __init__(self, kernel, memoryMana):
        threading.Thread.__init__(self)
        self.memoryMan = memoryMana
        self.kernel = kernel
        self.pc = None
        self.instruction = None
        self.running = False
        self.observerList = []

    def addObserver(self, observer):
        self.observerList.append(observer)
        
    def notifyObservers(self):
        for i in self.observerList:
            i.notify()
           
            
    def run(self):
        self.running = True      
        while self.running and not self.kernel.kernel_mode: # Mientras el CPU este corriendo
            if self.pc is not None:
                self.instruction = self.memoryMan.read(self.pc.pid, self.pc.pc)
                if self.instruction.opCode is 'End':
                    self.kernel.interrupt.interrupt('exit')

                elif self.instruction.opCode is "CPU":
                        print('[CPU] process ID:%s - instruction number:%s' % (self.pc.pid,self.pc.pc))
                        time.sleep(0.5) 
                        self.pc.incrementPc()
                        if len(self.observerList) > 0:
                            self.notifyObservers()
                elif self.instruction.opCode is "IO":
                    print('[IO] %s - %s' % (self.pc.pid, self.pc.pc))
                    self.pc.incrementPc()
                    time.sleep(0.5)
                    if self.kernel.timer is not None:
                        self.kernel.timer.restart()
                    self.kernel.interrupt.interrupt('ioReq')
                else:
                    self.kernel.interrupt.interrupt('kill')
            else:
                time.sleep(0.1) # idle
                
